package com.acme.bankapp.service.bank;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.Client;
import com.acme.exceptions.ClientExistException;
import com.acme.exceptions.NotEnoughFundsException;

public class BankService {

	public Bank bank;
	public BankDataLoaderService loader;
	ArrayList<ClientRegistrationListener> arrayList;
	private String serializeFile;

	private final static String savingAccount = "Saving account: ";
	private final static String checkingAccount = " Checking account: ";

	public BankService(final String serializeFile) {
		this.loader = new BankDataLoaderService();
		this.serializeFile = serializeFile;
		arrayList = new ArrayList<ClientRegistrationListener>();
		arrayList.add(new PrintClientListener());
		arrayList.add(new EmailNotificationListener());

		this.bank = new Bank(arrayList);
	}

	public int addClient(Client client) throws ClientExistException {
		for (int i = 0; i < bank.clients.size(); i++) {
			if (bank.clients.get(i).equals(client)) {
				throw new ClientExistException(i);
			}
		}

		bank.clients.add(client);
		for (ClientRegistrationListener listener : bank.listeners) {
			listener.onClientAdded(client);
		}
		return (bank.clients.size() - 1);
	}

	public void modifyBank(Client client, double amount, boolean meth)
			throws NotEnoughFundsException {
		if (meth == true) {
			client.accountS.deposit(amount);
		} else {
			client.accountC.withdraw(amount);
		}
		saveBank();
	}

	public void printBalance() {
		for (Client client : bank.clients) {
			if (client == null) {
				break;
			}
			System.out.println(client);

		}
	}

	public void printMaximumAmountToWidthdraw(Client client) {
		System.out.print(savingAccount
				+ client.accountS.maximumAmountToWithdraw());
		System.out.println(checkingAccount
				+ client.accountC.maximumAmountToWithdraw());
	}

	public void saveBank() {
		try {
			FileOutputStream fos = new FileOutputStream(serializeFile);
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			oos.writeObject(bank);
			oos.close();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void readBank() {
		Bank lastBank = bank;
		bank = new Bank(arrayList);
		try {
			FileInputStream fis = new FileInputStream(serializeFile);
			ObjectInputStream ois = new ObjectInputStream(fis);
			bank = (Bank) ois.readObject();
			System.out.println(bank);
			ois.close();
			fis.close();
		} catch (Exception e) {
			bank = lastBank;
			e.printStackTrace();
		}

	}

}
